#ifndef WWEBSOCKETSERVER_H
#define WWEBSOCKETSERVER_H

#include <cstring>
#include <map>
#include <random>
#include <chrono>
#include <mutex>
#include <shared_mutex>

#include "common.h"
#include "singleton.h"
#include "NedAllocatedObject.h"
#include "networkframemanager.h"

class WWebSocketServer;

// WebSocket操作码定义
enum WebSocketOpCode {
    CONTINUATION = 0x0,
    TEXT_FRAME   = 0x1,
    BINARY_FRAME = 0x2,
    CLOSE        = 0x8,
    PING         = 0x9,
    PONG         = 0xA
};

// 客户端信息结构
class WebSocketlientInfo : public NedAllocatedObject
{
public:
    WebSocketlientInfo(wxString cName,
                  WWebSocketServer *cServer);
    ~WebSocketlientInfo();

    bool IsHandshakeCompleted() const { return m_handshakeCompleted; }
    void SetHandshakeCompleted(bool completed) { m_handshakeCompleted = completed; }

    void deleteMe(void);
    // 处理WebSocket握手
    void HandleHandshake(void);
    // 处理WebSocket数据帧
    wxString HandleDataFrame(void);
    void RemoveDataFromMemoryBuffer(size_t pos, size_t len);
    // 构建WebSocket数据帧
    void BuildDataFrame(const wxString& message, WebSocketOpCode opcode, wxMemoryBuffer& frame);
    void OnWebSocketMessage(const wxString& message, WebSocketOpCode opcode);

    // 发送WebSocket消息
    bool SendMessage(const wxString& message, WebSocketOpCode opcode = TEXT_FRAME);
    bool Send(const void* data, size_t len);

    wxString clientName;
    wxSocketBase* socket;
    wxDateTime lastActiveTime;
    wxMemoryBuffer buffer;
    bool m_handshakeCompleted;
};

class WWebSocketServer : public wxEvtHandler
{
public:
    WWebSocketServer(wxString ip="127.0.0.1",
               int port=10051);
    ~WWebSocketServer();

    /// 打开服务器
    bool Open(void);
    /// 关闭服务器
    void Close(void);
    /// 设置服务器IP和端口
    bool setServerParams(wxString ip,int port);
    /// 得到当前系统操控客户端
    inline const WebSocketlientInfo* getOperClient(void) { return m_curOperClient; }
    /// 设置当前系统操控客户端
    inline void setOperClient(WebSocketlientInfo* client) { m_curOperClient = client; }
    /// 设置发送缓冲区大小
    inline void setSendBufferSize(uint32_t size) { m_sendbufsize = size; }
    /// 得到服务器IP
    inline wxString getServerIP(void) { return m_ServerIP; }
    /// 得到服务器端口
    inline int getServerPort(void) { return m_ServerPort; }
    /// 设置网络处理框架
    inline void setNetworkFrameManager(NetworkFrameManager *nfm) { m_NetworkFrameManager = nfm; }
    /// 得到网络处理框架
    inline NetworkFrameManager* getNetworkFrameManager(void) { return m_NetworkFrameManager; }

    // 发送WebSocket消息
    bool SendMessageAll(const wxString& message, WebSocketOpCode opcode = TEXT_FRAME,WebSocketlientInfo* client=NULL);
    bool SendMessageOther(const wxString& message, WebSocketOpCode opcode = TEXT_FRAME,WebSocketlientInfo* client=NULL);

private:
    void OnServerEvent(wxSocketEvent& event);
    void OnClientConnected(wxSocketBase* serverSock);
    void OnSocketData(wxSocketBase* clientSock);
    void OnClientDisconnected(wxSocketBase* clientSock);
    void OnClientClosedEvent(wxThreadEvent& event);
    void OnHeartTimeOutTimer(wxTimerEvent& event);

private:
    WebSocketlientInfo* FindClientId(wxSocketBase* sock);
    WebSocketlientInfo* FindClientName(wxString clientName);

private:
    wxString m_ServerIP;                                       /**< 服务器IP */
    int m_ServerPort;                                          /**< 服务器端口 */
    wxSocketServer* m_tcpserver;                               /**< tcp服务器管理 */
    std::map<wxSocketBase*, WebSocketlientInfo*> m_clients;    /**< 管理所有在线的tcp客户端 */
    mutable std::shared_mutex m_clientsMutex;                  /**< 保护所有的客户端 */
    wxTimer *m_HeartTimeOutTimer;                              /**< 心跳定时器 */
    NetworkFrameManager *m_NetworkFrameManager;                /**< 网络处理框架 */
    uint32_t m_sendbufsize;                                    /**< 发送缓冲区大小 */
    WebSocketlientInfo* m_curOperClient;                       /**< 当前操控系统的客户端 */
};

#endif // WWEBSOCKETSERVER_H
